﻿//
// Created by 小然 幸 on 2019/9/7.
//

#ifndef QTTCHANNEL_QTTVIDEO_H
#define QTTCHANNEL_QTTVIDEO_H

#ifndef QTT_PUBLIC
#if defined(_WIN32) || defined(__CYGWIN__)
#define QTT_PUBLIC_CALLBACK __stdcall
#define QTT_PUBLIC __declspec(dllexport)
#else
#define QTT_PUBLIC __attribute__((visibility("default")))
#endif
#endif

#include <cstdint>
#include <mutex>

namespace Qtt {
enum FrameFormat {
	NONE = 0,
	YUV420P = 1,
	BGR24 = 2,
	NV21 = 3,
	NV12 = 4,
	VIDEO_ENCODED = 5
};
class VideoFrame {
public:
	int width;
	int height;
	uint32_t timestamp;
	int key_frame;
	uint8_t *data;
	int data_len;
public:
	VideoFrame() {
		width = -1;
		height = -1;
		timestamp = 0;
		data = nullptr;
		data_len = 0;
	}
};

class VideoCapturer {
private:
	VideoFrame **mVideoFrame;
	std::mutex mMutex;
public:
	/**
	 * 构造函数
	 */
	QTT_PUBLIC VideoCapturer();
	/**
	 * 析构函数
	 */
	QTT_PUBLIC virtual ~VideoCapturer();
	/**
   	 * 给开发者准备的函数,当采集到数据,调用putFrame方法写入VideoCapturer
   	 * @param buf
   	 * @param size
   	 */
	QTT_PUBLIC void putFrame(uint8_t *buf, int size);
	QTT_PUBLIC void putFrame(VideoFrame *frame);
	/**
	 * 开发者不要调用该方法，这个会由内部调用
	 * @return 采集图像帧
	 */
	QTT_PUBLIC VideoFrame *getFrame();
	/**
	 * 设置采集图像的宽度，由开发者定义
	 * @return 宽度
	 */
	virtual int width() = 0;
	/**
	 * 设置采集图像的高度，由开发者定义
	 * @return 高度
	 */
	virtual int height() = 0;
	/**
	 * 设置视频的编码帧率
	 * @return 帧率
	 */
	virtual int fps() = 0;
	/**
	 * 设置视频的码率
	 * @return 比特率
	 */
	virtual int bps() = 0;
	/**
	 * 设置采集图像的格式
	 * @return 图像格式
	 */
	virtual FrameFormat captureFormat() = 0;
	/**
     * 开始工作,需要用户实现；在start被调用前，需设置好width等相关参数，会被框架取到使用
     * @return 0成功,其他失败
     */
	virtual int onStart() = 0;
	/**
     * 停止工作
     */
	virtual void onStop() = 0;
};

class VideoDisplayer {
public:
	/**
     * 开始工作,需要用户实现
     * @return 0成功,其他失败
     */
	virtual int onStart(uint32_t displayId, int width, int height) = 0;
	/**
     * 这个函数给播放对象用的,将frame显示出来
     */
	virtual void onDisplay(VideoFrame *frame, uint32_t displayId) = 0;
	/**
     * 停止工作
     */
	virtual void onStop(uint32_t displayId) = 0;
};

class VideoPlugin {
public:
	QTT_PUBLIC static void SetVideoCard(VideoCapturer *capturer, VideoDisplayer *displayer, FrameFormat displayFormat);
};

}

#endif //QTTCHANNEL_QTTVIDEO_H
